今天主要是要來介紹WebSocket,為何要介紹WebSocket呢?主要是因為在今年我參加了JCconf時有跟一位Line主管在詢問想當一個Web Service engineer 需要俱備哪些能力.在這裡來跟各位分享一下這個課題,如果我們的網路服務要供給上萬個或者百萬個人同時做請求時,我們有可能每一次都與Client使用TCP跟Client做溝通嗎?那當然是沒辦法達到一個及時的傳輸目的,那這之後還有幾個課題需要我們去做解決的,我回到家的時候自己做了點功課,如果想知道如何完成這樣的架構會需要用到負載平衡(Load balancing)概念,這部分可以參考Spring Cloud Netflix項目與解決方案的技術
那這邊我們不談到太遠的目標,我們先來撰寫個WebSocket programming吧
WebSocket是一個全雙工的通訊協定,協定就是雙方訂製的標準,雙方在溝通的時候要符合這個標準才能做溝通
ex:追妹子的時候要雙方同意交往彼此的距離關係才會更接近,這個解釋雖然不是完全正確,但是你可以想像的到的
WebSocket使client端與server的交換變得更簡單,省去了每次傳送資料都要跟你三問九叩的步驟,它使Server端可以主動向client發送資料
以前的網站要完成推播技術都是使用輪詢(Polling)技術來向client發送給用戶端瀏覽器,但是這個缺點瀏覽器需要不斷的對server發出請求,而且傳送的標頭檔也較長,通常會有個明顯的延遲
1.連線建立後每次傳輸所要帶的header變得更短了,讓交換訊息的速度加快了許多
2.全雙工,Server端能主動向client傳送訊息
3.可以達到持久層的連線,不需要每次都去詢問你再不在家
└── src
└── main
└── java
└── com.tutorial
└──WebSocketConfig.java
└──Tutorial2Application.java
└──ServletInitializer.java
└──Model
└──ChatClientModel.java
└──ServerResponseModel.java
└──Controller
└──CharRoomController.java
1.加入spring-boot-starter-websocket
依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.新增一個Model來建立一個接受訊息的Model
package com.tutorial.Model;
public class ChatClientModel {
private String Clientname;
public String getClientname() {
return Clientname;
}
public void setClientname(String clientname) {
Clientname = clientname;
}
}
3.新增一個Server端傳送給Client的Model
package com.tutorial.Model;
public class ServerResponseModel {
private String responseMessage;
public String getResponseMessage() {
return responseMessage;
}
public void setResponseMessage(String responseMessage) {
this.responseMessage = responseMessage;
}
}
4.建構一個WenSocketConfig類
注意!!警告!! 如果你的依賴有
spring-boot-starter-web
那這一步將會無法完成你會找不到AbstractWebSocketMessageBrokerConfigurer
的類別
package com.tutorial;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/endpointChatRoom").withSockJS();
}
}
@EnableWebSocketMessageBroker
註解是宣告啟用STOMP
協定,他是WebSocket的子協定來傳輸(message broker)消息,當註冊了之後控制器(Controller
)就能使用@MessageMapping
configureMessageBroker
方法是配製訊息代理(Message broker)registerStompEndpoints
方法是我們註冊了一個節點,用來映射指定URL,方法內註冊一個STOMP的endpoint,並且指定使用SockJS協定5.我們還要建構一個Controller來當我們的入口
package com.tutorial.Controller;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
import com.tutorial.Model.ChatClientModel;
import com.tutorial.Model.ServerResponseModel;
@Controller
public class CharRoomController {
@MessageMapping("/messageControl")
@SendTo("topic/getResponse")
public ServerResponseModel said(ChatClientModel responseMessage) throws InterruptedException{
Thread.sleep(3000);
return new ServerResponseModel("歡迎來到," + responseMessage.getClientname());
}
}
@MessageMapping
類似於@RequestMapping
1.此篇先介紹server端如何建構,下一篇建構client端並且做demo測試
2.我們需要建構兩個數據模型,一個是接收client訊息一個是發送給client訊息
3.這是一個廣播是的發送範例,如果你要的是一個獨立的私密聊天室你可以參考Spring Security將它整合在一起就可以達到你要的目的
4.下一篇會介紹Client如何完成我們的聊天室
5.這邊在強調一次這個範例不能加上spring-boot-starter-web
6.Spring Boot執行時會掃描group內的@Configuration
如果有@Enable...
將會啟用該配置
AbstractWebSocketMessageBrokerConfigurer过时
将extends AbstractWebSocketMessageBrokerConfigurer改为implements WebSocketMessageBrokerConfigurer